package com.gitee.ixtf.vertx.internal.converter

import com.gitee.ixtf.core.J
import com.gitee.ixtf.core.MAPPER
import com.gitee.ixtf.vertx.ParameterConverter
import graphql.schema.DataFetchingEnvironment
import io.vertx.core.buffer.Buffer
import io.vertx.core.eventbus.Message
import io.vertx.core.json.JsonArray
import io.vertx.core.json.JsonObject
import io.vertx.ext.web.FileUpload
import io.vertx.ext.web.RoutingContext
import java.lang.reflect.Parameter

class Body2AnyParameterConverter(private val parameter: Parameter) : ParameterConverter<Any?> {
  private fun convertBody(body: Any?): Any? =
      when (body) {
        is String -> J.inputCommand(body, parameter.type)
        is ByteArray -> J.inputCommand(body, parameter.type)
        is Buffer -> J.inputCommand(body.bytes, parameter.type)
        is JsonObject -> J.inputCommand(body.toBuffer().bytes, parameter.type)
        is JsonArray -> J.inputCommand(body.toBuffer().bytes, parameter.type)
        else -> body
      }

  override suspend fun convert(message: Message<*>) = message.body()?.let { convertBody(it) }

  override suspend fun convert(rc: RoutingContext) =
      rc.body()?.takeUnless { it.isEmpty }?.run { convertBody(buffer()) }

  override suspend fun convert(env: DataFetchingEnvironment): Any? =
      env.arguments
          .filterNot { (_, v) -> v is FileUpload }
          .let { J.inputCommand(MAPPER.convertValue(it, parameter.type)) }
}
